package brian.android.mvc.bean;

import java.util.HashMap;
import java.util.Map;

public abstract class AbstractBeanConfig implements BeanConfig {
	private Map<String, BeanConstructor> beanConstructorMap = new HashMap<String, BeanConstructor>();
	private boolean initialized;
	
	public void initBeans() {
		initialized = true;
		initializeBeans();
	}
	
	/**
	 * {@link BeanFactory} 에서 사용할 Bean 들을 선언한다. 
	 * */
	protected abstract void initializeBeans();

	@Override
	public BeanProxy addBean(String beanId, BeanConstructor beanConstructor) {
		beanConstructorMap.put(beanId, beanConstructor);
		return new BeanProxy(beanId, beanConstructor.getBeanType());
	}
	
	@Override
	public BeanProxy addBean(BeanConstructor beanConstructor) {
		String beanId = getBeanId(beanConstructor.getBeanType());
		return addBean(beanId, beanConstructor);
	}

	/**
	 * singleton 으로 Class명을 Id로 갖는 Bean을 추가한다. 
	 * */
	@SuppressWarnings("unchecked")
	public BeanProxy addBean(Class beanType, Object ... params) {
		String beanId = getBeanId(beanType);
		return addBean(beanId, true, beanType, params);
	}
	
	/**
	 * singleton 으로 Bean을 추가한다. 
	 * */
	@SuppressWarnings("unchecked")
	public BeanProxy addBean(String beanId, Class beanType, Object ... params) {
		return addBean(beanId, true, beanType, params);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public BeanProxy addBean(String beanId, boolean isSingleton, Class beanType, Object... params) {
		return addBean(beanId, new BeanConstructor(beanType, isSingleton, params));
	}
	
	@SuppressWarnings("unchecked")
	private String getBeanId(Class clazz) {
		String beanId = clazz.getSimpleName();
		return beanId.substring(0, 1).toLowerCase() + beanId.substring(1);
	}
	
	public Map<String, BeanConstructor> getBeanConstructorMap() {
		return beanConstructorMap;
	}

	@Override
	public boolean isInitialized() {
		return initialized;
	}
	
	@Override
	public boolean containsKey(String beanId) {
		return beanConstructorMap.containsKey(beanId);
	}
	
	@Override
	public BeanConstructor getBeanConstructor(String beanId) {
		return beanConstructorMap.get(beanId);
	}
}
